"""Script to generate Markdown documentation from tmt plans."""
import argparse
import json
import logging
from pathlib import Path
import subprocess
import typing

from cki_lib import logger
from cki_lib import misc
from cki_lib import session
import sentry_sdk
import yaml

LOGGER: logging.Logger = logger.get_logger('cki_tools.tmt_generate_test_plans_doc')
SESSION = session.get_session('cki_tools.tmt_generate_test_plans_doc', raise_for_status=True)


def gen_plan_doc(plan: dict) -> bool:
    """Generate documentation for the configured trees on given file."""
    basename = plan['name'].replace('/plans/', '')
    content = f"# {basename}\n"
    LOGGER.info("processing content of %s\n", plan['name'])
    content = []
    content.append(f"## {basename}\n")
    content.append(f"{plan['summary']}\n")
    content.append(f"- enabled: `{misc.booltostr(plan['enabled'])}`")
    if 'provision' in plan:
        content.append("- provision:")
        for entry in plan['provision']:
            if 'how' in entry:
                content.append(f"  - how: {entry['how']}")
            if 'image' in entry:
                content.append(f"  - image: `{entry['image']}`")
            if 'hardware' in entry:
                # hardware output can be very long, try to make it look nicer
                content.append("  - hardware:")
                content.append(f"`{json.dumps(entry['hardware'], indent=4)}`")
    content.append("- discover:")
    for entry in plan['discover']:
        if 'url' in entry:
            content.append(f"  - url: <{entry['url']}>")
        if 'filter' in entry:
            content.append(f"  - filter: `{entry['filter']}`")
        for selection in ['exclude', 'test']:
            if selection in entry:
                content.append(f"  - {selection}:")
                for value in entry[selection]:
                    content.append(f"    - {value}")
    content.append("")
    return content


# pylint: disable-msg=too-many-locals
def main(argv: typing.Optional[typing.List[str]] = None) -> int:
    """Script to generate Markdown documentation about the test plans."""
    parser = argparse.ArgumentParser(
        description='Generates Markdown files based on output of tmt plans export.')
    parser.add_argument('--plans-dir', default=".",
                        help='Path to repository with tmt plans')
    args = parser.parse_args(argv)

    basepath = args.plans_dir

    tmt_out = subprocess.run(['tmt', 'plans', 'export', '--format', 'yaml'],
                             check=True, capture_output=True, text=True, cwd=basepath).stdout
    tmt_plans = yaml.safe_load(tmt_out)

    all_content = {}
    for plan in tmt_plans:
        basename = plan['name'].replace('/plans/', '')
        parent = str(Path(basename).parent)
        if parent not in all_content:
            all_content[parent] = []
        all_content[parent].extend(gen_plan_doc(plan))

    child_pages = []
    for parent in sorted(all_content):
        if parent == '.':
            filename = 'documentation/README.md'
        else:
            filename = f'documentation/{parent}.md'
            child_pages.append(filename)

        LOGGER.debug("create file %s\n", filename)
        directory = Path(f'{basepath}/{filename}').parent
        Path(directory).mkdir(parents=True, exist_ok=True)
        with open(f'{basepath}/{filename}', 'w', encoding='utf-8') as file:
            file.write("<!-- markdownlint-disable-next-line MD041 -->\n")
            file.write("\n".join(all_content[parent]))
        LOGGER.debug("Generated content:\n")
        LOGGER.debug("\n".join(all_content[parent]))

    if child_pages:
        with open(f'{basepath}/documentation/README.md', 'a', encoding='utf-8') as file:
            file.write("\nMore test plans can be found at:\n")
            file.write("\n")

    for page in sorted(child_pages):
        content = []
        name = page.replace('documentation/', '')
        name = name.replace('.md', '')
        link = f"- [{name}]({page})"
        content.append(link)
        with open(f'{basepath}/documentation/README.md', 'a', encoding='utf-8') as file:
            file.write("\n".join(content))
            file.write("\n")

    return 0


if __name__ == '__main__':
    misc.sentry_init(sentry_sdk)
    main()
